#!/bin/bash
# File: cpu.bashunit
# Bashunit test for the cpu.sh
# Copyright (c) 2010 Radek Hnilica

# If we press RESSET button, some registers must come in predefined state.
test_reset() {
    reg_pc=1
    reg_ac=2
    reg_l=1
    cpu_reset
    assert_equal $reg_pc 0
    assert_equal $reg_ac 0
    assert_equal $reg_l 0
}

test_pc_advance_in_step() {
    loadRIM pdp8progs/nop.rim	# Load program
    cpu_reset
    cpu_step
    assert_equal 1 $reg_pc
    reg_pc=4095
    cpu_step
    assert_equal 0 $reg_pc
}

test_get_ea() {
    # Direct Addressing
    reg_ir=$((0000))
    assert_equal 0 $(cpu_get_ea) # Direct, ZeroPage, 0
    reg_ir=$((0177))
    assert_equal $(( 0177 )) $(cpu_get_ea) # D,ZP,0177
    reg_ir=$((0200)); reg_pc=$((0400))
    assert_equal $((0400)) $(cpu_get_ea) # D,CP,0
    reg_ir=$((0377)); reg_pc=$((0400))
    assert_equal $((0577)) $(cpu_get_ea) # D,CP,0177

    # Indirect Addressing, Zero Page
    reg_ir=$((0400)); memory_write 1 0
    assert_equal 1 $(cpu_get_ea)
}


test_run_hlt() {
    loadRIM pdp8progs/test_run_hlt.rim
    cpu_reset
    cpu_run
    assert_equal 3 $reg_pc
    cpu_run
    assert_equal 7 $reg_pc
    assert_equal 3 $reg_ac
    cpu_run 2
    assert_equal $((011)) $reg_pc
    assert_equal 5 $reg_ac
}


test_tad() {
    loadRIM pdp8progs/test_tad.rim # Load program
    cpu_reset			# ac==0
    cpu_step
    assert_equal $((05555)) $reg_ac
    cpu_step
    assert_equal $((07777)) $reg_ac
}

test_tad_l() {
    loadRIM pdp8progs/test_tad_l.rim # Load program
    cpu_reset
    cpu_step
    cpu_step
    assert_equal 1 $reg_l
    assert_equal 0 $reg_ac
}

test_and() {
    loadRIM pdp8progs/test_and.rim # Load program
    cpu_reset
    cpu_step
    cpu_step
    assert_equal $((02222)) $reg_ac
}

test_isz() {
    loadRIM pdp8progs/test_isz.rim # Load program
    cpu_reset
    cpu_step			# First step/run should 
    # Now pc should be 2 and VAR should be 0
    assert_equal $((0)) $(memory_read 00077)
    assert_equal 2 $reg_pc
    cpu_reset
    cpu_step
    assert_equal 1 $(memory_read 00077)
    assert_equal 1 $reg_pc
}


test_dca() {
    loadRIM pdp8progs/test_dca.rim
    cpu_reset
    cpu_step
    cpu_step
    assert_equal 0 $reg_ac
    assert_equal $((05252)) $(memory_read 00171)
}


test_subroutine() {
    loadRIM pdp8progs/test_subroutine.rim
    cpu_reset
    cpu_step				# pc=101
    assert_equal $((0101)) $reg_pc # jump
    assert_equal 1 $(memory_read 00100) # stored address
    cpu_step				# pc=102
    cpu_step			# return (pc=1)
    assert_equal 1 $reg_pc
}

# Test Clear and Complement microinstruction from the Operate group 1.
test_cl_and_cm() {
    loadRIM pdp8progs/test_clear_and_complement.rim
    cpu_reset
    cpu_step			# TAD 5252
    assert_equal $((05252)) $reg_ac
    cpu_step			# CMA
    assert_equal $((02525)) $reg_ac
    cpu_step			# CLA
    assert_equal 0 $reg_ac
    assert_equal 0 $reg_l
    cpu_step			# IAC
    assert_equal 1 $reg_ac
    assert_equal 0 $reg_l
    cpu_step			# RAR
    assert_equal 1 $reg_l
    assert_equal 0 $reg_ac
    cpu_step			# CML
    assert_equal 0 $reg_l
    assert_equal 0 $reg_ac
    cpu_step			# CLL
    assert_equal 1 $reg_l
    assert_equal 0 $reg_ac
    cpu_step			# RAL
    assert_equal 0 $reg_l
    assert_equal 1 $reg_ac
}

# Test Simple Rotate instructions RAL and RAR
test_simple_rotate() {
    loadRIM pdp8progs/test_simple_rotate.rim
    cpu_reset
    cpu_step			# TAD 5252
    assert_equal 0 $reg_l
    assert_equal $((05252)) $reg_ac
    cpu_step			# RAL
    assert_equal 1 $reg_l
    assert_equal $((02524)) $reg_ac
    cpu_step			# RAL
    assert_equal 0 $reg_l
    assert_equal $((05251)) $reg_ac
    cpu_step			# RAR
    assert_equal 1 $reg_l
    assert_equal $((02524)) $reg_ac
    cpu_step			# RAR
    assert_equal 0 $reg_l
    assert_equal $((05252)) $reg_ac
}

# Test Double Rotate instructions RTL and RTR
test_double_rotate() {
    loadRIM pdp8progs/test_double_rotate.rim
    cpu_reset
    cpu_step			# TAD 5252
    assert_equal 0 $reg_l
    assert_equal $((05252)) $reg_ac
    cpu_step			# RTL
    assert_equal 0 $reg_l
    assert_equal $((05251)) $reg_ac
    cpu_step			# RTR
    assert_equal 0 $reg_l
    assert_equal $((05252)) $reg_ac
}

### Testing Group 2 Microinstructions
test_cla_group2() {
    loadRIM pdp8progs/test_cla_group2.rim
    cpu_reset
    cpu_step			# TAD 5252
    assert_equal $((05252)) $reg_ac
    cpu_step			# CLA Gr2
    assert_equal 0 $reg_ac
}

test_sma_spa_skp() {
    loadRIM pdp8progs/test_sma_spa_skp.rim
    cpu_reset
    cpu_step			# CLA /AC=0
    assert_equal 0 $reg_ac
    cpu_step			# SMA /AC=0
    assert_equal 2 $reg_pc
    cpu_step			# SPA /AC=0
    assert_equal 4 $reg_pc

    cpu_step			# CMA
    assert_equal $((07777)) $reg_ac
    cpu_step			# SPA
    assert_equal 6 $reg_pc
    cpu_step			# SMA
    assert_equal $((0010)) $reg_pc

    cpu_step			# SKP
    assert_equal $((0012)) $reg_pc
}


test_sza_sna() {
    loadRIM pdp8progs/test_sza_sna.rim
    cpu_reset
    cpu_step			# CLA /AC=0 (zero)
    assert_equal 0 $reg_ac
    cpu_step			# SNA /AC=0
    assert_equal 2 $reg_pc
    cpu_step			# SZA /AC=0
    assert_equal 4 $reg_pc

    cpu_step			# IAC /AC=1 (nonzero)
    assert_equal 1 $reg_ac
    cpu_step			# SZA
    assert_equal 6 $reg_pc
    cpu_step			# SNA
    assert_equal $((0010)) $reg_pc
}


test_snl_szl() {
    loadRIM pdp8progs/test_snl_szl.rim
    cpu_reset
    cpu_step			# CLL
    assert_equal 0 $reg_l
    cpu_step			# SNL
    assert_equal 2 $reg_pc
    cpu_step			# SZL
    assert_equal 4 $reg_pc

    cpu_step			# CML
    assert_equal 1 $reg_l
    cpu_step			# SZL
    assert_equal 6 $reg_pc
    cpu_step			# SNL
    assert_equal $((0010)) $reg_pc
}

### Small programs
test_mult_18_by_36() {
    loadRIM pdp8progs/test_mult_18_by_36.rim
    cpu_reset
    reg_pc=$((0200))
    cpu_run 500
    assert_equal $((0210)) $reg_pc
    assert_equal $((36*18)) $reg_ac
}

source memory.sh
source cpu.sh
source rim-loader.sh

#Local variables:
#mode: shell-script
#coding: utf-8
#End:
